#include <iostream>
#include <vector>
#include <complex>
#include <cmath>
#include <algorithm>
#include <cstdint>
using namespace std;

struct BigIntSimple {
    static const int BIGINT_BASE = 10000;
    static const int BIGINT_DIGITS = 4;

    int sign; // 1表示正数，-1表示负数
    std::vector<int> v;

    //定义0也需要长度1
    BigIntSimple() {
        sign = 1;
        v.push_back(0);
    }
    BigIntSimple(int n) { *this = n; }
    //判断是否为0
    bool iszero() const { return v.size() == 1 && v.back() == 0; }
    //消除前导0并修正符号
    void trim() {
        while (v.back() == 0 && v.size() > 1)
            v.pop_back();
        if (iszero()) sign = 1;
    }
    //获取pos位置上的数值，用于防越界，简化输入处理
    int get(unsigned pos) const {
        if (pos >= v.size()) return 0;
        return v[pos];
    }
    //绝对值大小比较
    bool absless(const BigIntSimple &b) const {
        if (v.size() == b.v.size()) {
            for (size_t i = v.size() - 1; i < v.size(); --i)
                if (v[i] != b.v[i]) return v[i] < b.v[i];
            return false;
        } else {
            return v.size() < b.v.size();
        }
    }
    //字符串输入
    void set(const char *s) {
        v.clear();
        sign = 1;
        //处理负号
        while (*s == '-')
            sign = -sign, ++s;
        //先按数位直接存入数组里
        for (size_t i = 0; s[i]; ++i)
            v.push_back(s[i] - '0');
        std::reverse(v.begin(), v.end());
        //压位处理，e是压位后的长度
        size_t e = (v.size() + BIGINT_DIGITS - 1) / BIGINT_DIGITS;
        for (size_t i = 0, j = 0; i < e; ++i, j += BIGINT_DIGITS) {
            v[i] = v[j]; //设置压位的最低位
            //高位的按每一位上的数值乘以m，m是该位的权值
            for (size_t k = 1, m = 10; k < BIGINT_DIGITS; ++k, m *= 10)
                v[i] += get(j + k) * m;
        }
        //修正压位后的长度
        if (e) {
            v.resize(e);
            trim();
        } else {
            v.resize(1);
        }
    }
    //分治进制转换输入
    BigIntSimple &_from_str(const std::string &s, int base) {
        //较短长度时直接计算，36^4 < 2^31，但取5就大于了，所以长度上限是4
        if (s.size() <= 4) {
            int v = 0;
            for (size_t i = 0; i < s.size(); ++i) {
                int digit = -1;
                if (s[i] >= '0' && s[i] <= '9')
                    digit = s[i] - '0';
                else if (s[i] >= 'A' && s[i] <= 'Z')
                    digit = s[i] - 'A' + 10;
                else if (s[i] >= 'a' && s[i] <= 'z')
                    digit = s[i] - 'a' + 10;
                v = v * base + digit;
            }
            return *this = v;
        }
        BigIntSimple m(base), h;
        size_t len = 1;
        //计算分割点
        for (; len * 3 < s.size(); len *= 2) {
            m = m * m;
        }
        h._from_str(s.substr(0, s.size() - len), base);
        _from_str(s.substr(s.size() - len), base);
        *this = *this + m * h;
        return *this;
    }
    //任意进制字符串输入（2~36进制）
    BigIntSimple &from_str(const char *s, int base = 10) {
        //特殊情况直接用原来的读入函数速度快
        if (base == 10) {
            set(s);
            return *this;
        }
        int vsign = 1, i = 0;
        while (s[i] == '-') {
            ++i;
            vsign = -vsign;
        }
        _from_str(std::string(s + i), base);
        sign = vsign;
        return *this;
    }
    //字符串输出
    std::string to_dec() const {
        std::string s;
        for (size_t i = 0; i < v.size(); ++i) {
            int d = v[i];
            //拆开压位
            for (size_t k = 0; k < BIGINT_DIGITS; ++k) {
                s += d % 10 + '0';
                d /= 10;
            }
        }
        //去除前导0
        while (s.size() > 1 && s.back() == '0')
            s.pop_back();
        //补符号
        if (sign < 0) s += '-';
        //不要忘记要逆序
        std::reverse(s.begin(), s.end());
        return s;
    }
    //递归分治进制转换输出
    std::string _to_str(int base, int pack) const {
        std::string s;
        //长度只剩下2时可以直接算
        if (v.size() <= 2) {
            int d = v[0] + (v.size() > 1 ? v[1] : 0) * BIGINT_BASE;
            do {
                int g = d % base;
                if (g < 10) {
                    s += char(g + '0');
                } else {
                    s += char(g + 'a' - 10);
                }
                d /= base;
            } while (d);
            //填充前导0
            size_t pack_temp = pack;
            while (s.size() < pack_temp)
                s += '0';
            std::reverse(s.begin(), s.end());
            return s;
        }
        BigIntSimple m(base), h, l;
        size_t len = 1; //计算余数部分要补的前导0
        //计算分割点
        for (; m.v.size() * 3 < v.size(); len *= 2) {
            m = m * m;
        }
        h = div_mod(m, l); //算出分割后的高位h和低位l
        s = h._to_str(base, std::max(pack - (int)len, 0));
        return s + l._to_str(base, len);
    }
    //任意进制（2~36进制）字符串输出
    std::string to_str(int base = 10) const {
        if (base == 10) {
            return to_dec();
        }
        std::string s;
        BigIntSimple m(*this);
        m.sign = 1;
        s = m._to_str(base, 0);
        return sign >= 0 ? s : "-" + s;
    }

    bool operator<(const BigIntSimple &b) const {
        if (sign == b.sign) {
            return sign > 0 ? absless(b) : b.absless(*this);
        } else {
            return sign < 0;
        }
    }

    bool operator==(const BigIntSimple &b) const {
        if (sign == b.sign) {
            return !absless(b) && !b.absless(*this);
        }
        return false;
    }

    BigIntSimple &operator=(int n) {
        v.clear();
        sign = n >= 0 ? 1 : -1;
        for (n = abs(n); n; n /= BIGINT_BASE)
            v.push_back(n % BIGINT_BASE);
        if (v.empty()) v.push_back(0);
        return *this;
    }

    BigIntSimple &operator=(const std::string &s) {
        set(s.c_str());
        return *this;
    }

    BigIntSimple operator-() const {
        BigIntSimple r = *this;
        r.sign = -r.sign;
        return r;
    }

    BigIntSimple operator+(const BigIntSimple &b) const {
        //符号不同时转换为减法
        if (sign != b.sign) return *this - -b;
        BigIntSimple r = *this;
        //填充高位
        if (r.v.size() < b.v.size()) r.v.resize(b.v.size());
        int carry = 0;
        //逐位相加
        for (size_t i = 0; i < b.v.size(); ++i) {
            carry += r.v[i] + b.v[i] - BIGINT_BASE;
            r.v[i] = carry - BIGINT_BASE * (carry >> 31);
            carry = (carry >> 31) + 1;
        }
        //处理进位，拆两个循环来写是避免做 i < b.v.size() 的判断
        for (size_t i = b.v.size(); carry && i < r.v.size(); ++i) {
            carry += r.v[i] - BIGINT_BASE;
            r.v[i] = carry - BIGINT_BASE * (carry >> 31);
            carry = (carry >> 31) + 1;
        }
        //处理升位进位
        if (carry) r.v.push_back(carry);
        return r;
    }

    BigIntSimple &subtract(const BigIntSimple &b) {
        int borrow = 0;
        //先处理b的长度
        for (size_t i = 0; i < b.v.size(); ++i) {
            borrow += v[i] - b.v[i];
            v[i] = borrow;
            v[i] -= BIGINT_BASE * (borrow >>= 31);
        }
        //如果还有借位就继续处理
        for (size_t i = b.v.size(); borrow; ++i) {
            borrow += v[i];
            v[i] = borrow;
            v[i] -= BIGINT_BASE * (borrow >>= 31);
        }
        //减法可能会出现前导0需要消去
        trim();
        return *this;
    }

    BigIntSimple operator-(const BigIntSimple &b) const {
        //符号不同时转换为加法
        if (sign != b.sign) return (*this) + -b;
        if (absless(b)) { //保证大数减小数
            BigIntSimple r = b;
            return -r.subtract(*this);
        } else {
            BigIntSimple r = *this;
            return r.subtract(b);
        }
    }

    BigIntSimple &offset_add(const BigIntSimple &b, int offset) {
        //填充高位
        if (v.size() < b.v.size() + offset) v.resize(b.v.size() + offset);
        int carry = 0;
        //逐位相加
        for (size_t i = 0; i < b.v.size(); ++i) {
            carry += v[i + offset] + b.v[i] - BIGINT_BASE;
            v[i + offset] = carry - BIGINT_BASE * (carry >> 31);
            carry = (carry >> 31) + 1;
        }
        //处理进位，拆两个循环来写是避免做 i < b.v.size() 的判断
        for (size_t i = b.v.size() + offset; carry && i < v.size(); ++i) {
            carry += v[i] - BIGINT_BASE;
            v[i] = carry - BIGINT_BASE * (carry >> 31);
            carry = (carry >> 31) + 1;
        }
        //处理升位进位
        if (carry) v.push_back(carry);
        return *this;
    }

    BigIntSimple mul(const BigIntSimple &b) const {
        // r记录相加结果
        BigIntSimple r;
        r.v.resize(v.size() + b.v.size()); //初始化长度
        for (size_t j = 0; j < v.size(); ++j) {
            int carry = 0, m = v[j]; // m用来缓存乘数
            // carry可能很大，只能使用求模的办法，此循环与加法部分几乎相同，就多乘了个m
            for (size_t i = 0; i < b.v.size(); ++i) {
                carry += r.v[i + j] + b.v[i] * m;
                r.v[i + j] = carry % BIGINT_BASE;
                carry /= BIGINT_BASE;
            }
            r.v[j + b.v.size()] += carry;
        }
        r.trim();
        return r;
    }

    BigIntSimple &fastmul(const BigIntSimple &a, const BigIntSimple &b) {
        //小于某个阈值就直接用暴力乘法
        if (std::min(a.v.size(), b.v.size()) <= 300) {
            return *this = a.mul(b);
        }
        BigIntSimple ah, al, bh, bl, h, m;
        //计算分割点
        size_t split = std::max(                            //
            std::min((a.v.size() + 1) / 2, b.v.size() - 1), //
            std::min((b.v.size() + 1) / 2, a.v.size() - 1));
        //按分割点拆成4个数
        al.v.assign(a.v.begin(), a.v.begin() + split);
        ah.v.assign(a.v.begin() + split, a.v.end());
        bl.v.assign(b.v.begin(), b.v.begin() + split);
        bh.v.assign(b.v.begin() + split, b.v.end());
        //按公式递归计算
        fastmul(al, bl);
        h.fastmul(ah, bh);
        m.fastmul(al + ah, bl + bh);
        m.subtract(*this + h);
        v.resize(a.v.size() + b.v.size());

        offset_add(m, split);
        offset_add(h, split * 2);
        trim();
        return *this;
    }

    BigIntSimple operator*(const BigIntSimple &b) const {
        BigIntSimple r;
        r.fastmul(*this, b);
        // r = mul(b);
        r.sign = sign * b.sign;
        return r;
    }

    //对b乘以mul再左移offset的结果相减，为除法服务
    BigIntSimple &sub_mul(const BigIntSimple &b, int mul, int offset) {
        if (mul == 0) return *this;
        int borrow = 0;
        //与减法不同的是，borrow可能很大，不能使用减法的写法
        for (size_t i = 0; i < b.v.size(); ++i) {
            borrow += v[i + offset] - b.v[i] * mul - BIGINT_BASE + 1;
            v[i + offset] = borrow % BIGINT_BASE + BIGINT_BASE - 1;
            borrow /= BIGINT_BASE;
        }
        //如果还有借位就继续处理
        for (size_t i = b.v.size(); borrow; ++i) {
            borrow += v[i + offset] - BIGINT_BASE + 1;
            v[i + offset] = borrow % BIGINT_BASE + BIGINT_BASE - 1;
            borrow /= BIGINT_BASE;
        }
        return *this;
    }

    BigIntSimple div_mod(const BigIntSimple &b, BigIntSimple &r) const {
        BigIntSimple d;
        r = *this;
        if (absless(b)) return d;
        d.v.resize(v.size() - b.v.size() + 1);
        //提前算好除数的最高三位+1的倒数，若最高三位是a3,a2,a1
        //那么db是a3+a2/base+(a1+1)/base^2的倒数，最后用乘法估商的每一位
        //此法在BIGINT_BASE<=32768时可在int32范围内用
        //但即使使用int64，那么也只有BIGINT_BASE<=131072时可用（受double的精度限制）
        //能保证估计结果q'与实际结果q的关系满足q'<=q<=q'+1
        //所以每一位的试商平均只需要一次，只要后面再统一处理进位即可
        //如果要使用更大的base，那么需要更换其它试商方案
        double t = (b.get((unsigned)b.v.size() - 2) + (b.get((unsigned)b.v.size() - 3) + 1.0) / BIGINT_BASE);
        double db = 1.0 / (b.v.back() + t / BIGINT_BASE);
        for (size_t i = v.size() - 1, j = d.v.size() - 1; j <= v.size();) {
            int rm = r.get(i + 1) * BIGINT_BASE + r.get(i);
            int m = std::max((int)(db * rm), r.get(i + 1));
            r.sub_mul(b, m, j);
            d.v[j] += m;
            if (!r.get(i + 1)) //检查最高位是否已为0，避免极端情况
                --i, --j;
        }
        r.trim();
        //修正结果的个位
        int carry = 0;
        while (!r.absless(b)) {
            r.subtract(b);
            ++carry;
        }
        //修正每一位的进位
        for (size_t i = 0; i < d.v.size(); ++i) {
            carry += d.v[i];
            d.v[i] = carry % BIGINT_BASE;
            carry /= BIGINT_BASE;
        }
        d.trim();
        return d;
    }

    //返回右移后的结果
    BigIntSimple shr_to(size_t n) const {
        BigIntSimple r;
        if (n >= v.size()) return r;
        r.v.assign(v.begin() + n, v.end());
        return r;
    }

    //对自身左移
    BigIntSimple &shl(size_t n) {
        if (n == 0) return *this;
        v.insert(v.begin(), n, 0);
        return *this;
    }

    //分治除法递归部分
    BigIntSimple &dividediv_recursion(const BigIntSimple &a, const BigIntSimple &b, BigIntSimple &r) {
        if (a < b) {
            r = a;
            return *this = BigIntSimple(0);
        } else if (b.v.size() <= 300) {
            return *this = a.div_mod(b, r);
        }
        size_t base = (b.v.size() + 1) / 2;
        //符合3/2时，进行试商
        if (a.v.size() <= base * 3) {
            base = b.v.size() / 2;
            BigIntSimple ma = a, mb = b, e;
            BigIntSimple ha = ma.shr_to(base);
            BigIntSimple hb = mb.shr_to(base);
            dividediv_recursion(ha, hb, r);
            ha = *this * b;
            while (a < ha) {
                ha.subtract(b);
                subtract(BigIntSimple(1));
            }
            r = a - ha;
            return *this;
        }
        //选择合适的base长度做分割
        if (a.v.size() > base * 4) base = a.v.size() / 2;
        BigIntSimple ha = a.shr_to(base);
        BigIntSimple c, d, m;
        dividediv_recursion(ha, b, d);
        shl(base);
        m.v.resize(base + d.v.size());
        for (size_t i = 0; i < base; ++i)
            m.v[i] = a.v[i];
        for (size_t i = 0; i < d.v.size(); ++i)
            m.v[base + i] = d.v[i];
        *this = *this + c.dividediv_recursion(m, b, r);
        return *this;
    }

    //分治除法规则化准备
    BigIntSimple &dividediv(const BigIntSimple &a, const BigIntSimple &b, BigIntSimple &r) {
        if (b.v.size() <= 300) {
            return *this = a.div_mod(b, r);
        }
        //被除数不及两倍除数长度减2时，可以忽略一部分最低位且不影响结果
        if (b.v.size() * 2 - 2 > a.v.size()) {
            BigIntSimple ta = a, tb = b;
            size_t ans_len = a.v.size() - b.v.size() + 2;
            size_t shr = b.v.size() - ans_len;
            ta = ta.shr_to(shr);
            tb = tb.shr_to(shr);
            return dividediv(ta, tb, r);
        }
        //规则化
        int mul = (int)(((uint64_t)BIGINT_BASE * BIGINT_BASE - 1) /                //
                        (*(b.v.begin() + b.v.size() - 1) * (uint64_t)BIGINT_BASE + //
                         *(b.v.begin() + b.v.size() - 2) + 1));
        BigIntSimple ma = BigIntSimple(mul) * a;
        BigIntSimple mb = BigIntSimple(mul) * b;
        BigIntSimple d;
        ma.sign = mb.sign = 1;
        dividediv_recursion(ma, mb, d);
        r = d.div_mod(BigIntSimple(mul), ma);
        return *this;
    }

    BigIntSimple operator/(const BigIntSimple &b) const {
        BigIntSimple r, t;
        // t = div_mod(b, r);
        t.dividediv(*this, b, r);
        t.sign = sign * b.sign;
        return t;
    }

    BigIntSimple operator%(const BigIntSimple &b) const { return *this - *this / b * b; }
};

// Function to calculate factorial mod
BigIntSimple factorial(int n) {
    BigIntSimple res = BigIntSimple(1);
    for (int i = 2; i <= n; ++i) {
        res = res * BigIntSimple(i);
    }
    return res;
}

// Function to calculate C(n, k)
BigIntSimple comb(int n, int k) {
    if (k > n) return 0;
    BigIntSimple res(1);
    if (k == 0 || k == n) return res;

    for (int i = 0; i < k; ++i) {
        res = res *  BigIntSimple(n - i);
        res = res / BigIntSimple(i + 1);
    }
    return res;
}

int main() {
    string line;
    vector<string> res;

    while (getline(cin, line)) {
        if (line.empty())
            break;
        stringstream ss(line);
        int n, k;
        ss >> n >> k;

        int m = n / k;
        BigIntSimple result(1);
        // 计算分堆方式
        for (int i = 0; i < k; i++) {
            result = result * comb(n - i * m, m);
        }

        // 除以 k!，因为顺序不同的堆视为相同
        result = result / factorial(k);

        res.push_back(result.to_str(10));
    }

    for (string val : res)
        cout << val << endl;
    return 0;
}